/*
LICENCIA
========
Copyright (C) 2009

Autores:

Carlos Alberto Martínez Gadea   <camg6@alu.ua.es>
Manel Simon Martínez            <msm85@alu.ua.es>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TLISTA_H
#define TLISTA_H

#include <iostream>
#include <stdlib.h>
#include <cstring>
#include <sstream>

using namespace std;

class TListaNodo;

class TLista
{
    friend class TListaNodo;

    public:
        TLista();
        TLista(const TLista& );
        ~TLista();

        TLista& operator=(const TLista& );

        TListaNodo* PrimerHueco(int );
        TListaNodo* PeorHueco();
        TListaNodo* MejorHueco(int );
        TListaNodo* SiguienteHueco(int );
        bool CargarProceso( TListaNodo* , const TListaNodo& );
        bool InsCabeza(const TListaNodo& );
        bool InsertarD(const TListaNodo& ,TListaNodo* );
        bool LiberarParticion(string );
        bool JuntarHuecos(TListaNodo*, TListaNodo*);
        void ReservarEspacio(string,ofstream&);
        void ReservaYCompacta(string,ofstream&);
        void SetAlgoritmo(string, ofstream&);
        void AccederDireccion(string, int, ofstream&);
        void Compacta();
        void AjustaReg();
        bool NecesarioCompactar(int);
        void AmpliarParticion(string,ofstream&);

        int Long() const;
        int GetAlgoritmo() const { return alg_vigente; };
        bool EsVacia() const { return (cabeza==NULL);};
        TListaNodo* GetCabeza() const   { return cabeza;};
        int getHuecoTotal() { return hueco_total; }

    private:
        TListaNodo* cabeza;
        TListaNodo* cola;
        TListaNodo* ultimo_insertado;
        int alg_vigente;
        int hueco_total;
};

class TListaNodo
{
    friend class TLista;

    public:
        TListaNodo();
        /* Constructor usado en el operator= y constructor copia */
        TListaNodo(int id, int reg_limite, int reg_base);
        /* Constructor que debe usarse por defecto para crear nodos */
        TListaNodo(string prog, int reg_limite);
        TListaNodo(const TListaNodo& );
        ~TListaNodo();

        TListaNodo& operator=(const TListaNodo& );

        void SetRegBase(int b)  { reg_base = b;};
        void SetRegLim(int l)   { reg_limite = l;};
        void SetId(int p)       { id = p;};
        void SetAsign(bool s)   { asignado = s;};
        void SetSO()	        { so = true;};
        void SetProg(string p)  { prog = p;};

        int GetRegBase() const  { return reg_base; };
        int GetRegLim() const   { return reg_limite; };
        int GetId() const       { return id; };
        bool Asignado() const   { return asignado; };
        bool IsSO() const       { return so; };
        string GetProg() const  { return prog; };

        TListaNodo* SetSig(TListaNodo *next)    { return (sig = next); };
        TListaNodo* GetSig() const              { return sig; };

    private:
        int reg_base /* Dirección física de comienzo */;
        int reg_limite /* Tamaño del programa */;
        int id /* Numero de la partición */;
        bool asignado;
        bool so /* True si es SO false en caso contrario */;
        string prog /* Nombre del programa */;

        TListaNodo* sig;
};

#endif // TLISTA_H
